﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace MyDLL
{
    public class BasicDataProcess_Common
    {
        /// <summary>
        /// DataType
        /// </summary>
        public enum DataType
        {
            Boolean,
            Byte,
            Char,
            DateTime,
            Decimal,
            Double,
            Int16,
            Int32,
            Int64,
            SByte,
            Single,
            String,
            TimeSpan,
            UInt16,
            UInt32,
            UInt64
        }

        /// <summary>
        /// 将字符串转化为整形数组，以","分隔。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int[] String_to_IntArr(string str)
        {
            return Array.ConvertAll<string, int>(str.Split(','), s => int.Parse(s));
        }

        /// <summary>
        /// 将字符串转换为整形数字（int.Parse)。
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>返回整形数字</returns>
        public static int String_to_Int(string str)
        {
            return int.Parse(str);
        }
        /// <summary>
        /// 将字符串数组转化为整形数组。
        /// </summary>
        /// <param name="strArr"></param>
        /// <param name="isTrim">是否Trim，默认为false</param>
        /// <returns></returns>
        public static int[] StringArr_to_IntArr(string[] strArr, bool isTrim = false)
        {
            if (!isTrim)
                return Array.ConvertAll<string, int>(strArr, s => int.Parse(s));
            else
                return Array.ConvertAll<string, int>(strArr, s => int.Parse(s.Trim()));
        }
        /// <summary>
        /// 将整形数组转化为字符串数组。
        /// </summary>
        /// <param name="intArr"></param>
        /// <returns></returns>
        public static string[] IntArr_to_StringArr(int[] intArr)
        {
            return Array.ConvertAll<int, string>(intArr, s => s.ToString());
        }

        /// <summary>
        /// Trim一维字符串数组
        /// </summary>
        /// <param name="strArr0">原字符串数组</param>
        /// <returns>返回Trim后的字符串数组</returns>
        public static string[] StringArrTrim(string[] strArr0)
        {
            string[] strArr = new string[strArr0.Length];
            for (int i = 0; i < strArr0.Length; i++)
            {
                strArr[i] = strArr0[i].Trim();
            }
            return strArr;
        }

        /// <summary>
        /// 从二维数组中获取指定行的全部元素，并以一维数组的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <param name="rowIndex">指定的行号</param>
        /// <returns>返回一维数组</returns>
        public static T[] GetRowFrom2DArray<T>(T[,] Arr2D, int rowIndex)
        {
            T[] resArr = new T[Arr2D.GetLength(1)];
            for (int i = 0; i < Arr2D.GetLength(1); i++)
            {
                resArr[i] = Arr2D[rowIndex, i];
            }
            return resArr;
        }

        /// <summary>
        /// 从二维数组中获取指定多行的全部元素，并以二维数组的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <param name="rowIndexes">指定的行号（多行）</param>
        /// <returns>返回二维数组</returns>
        public static T[,] GetRowsFrom2DArray<T>(T[,] Arr2D, int[] rowIndexes)
        {
            T[,] resArr = new T[rowIndexes.Length, Arr2D.GetLength(1)];
            for (int i = 0; i < rowIndexes.Length; i++)
            {
                for (int j = 0; j < Arr2D.GetLength(1); j++)
                {
                    resArr[i, j] = Arr2D[i, j];
                }
            }
            return resArr;
        }

        /// <summary>
        /// 从二维数组中获取指定列的全部元素，并以一维数组的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <param name="colIndex">指定的列号</param>
        /// <returns>返回一维数组</returns>
        public static T[] GetColumnFrom2DArray<T>(T[,] Arr2D, int colIndex)
        {
            T[] resArr = new T[Arr2D.GetLength(0)];
            for (int i = 0; i < Arr2D.GetLength(0); i++)
            {
                resArr[i] = Arr2D[i, colIndex];
            }
            return resArr;
        }

        /// <summary>
        /// 从二维数组中获取指定多列的全部元素，并以二维数组的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <param name="colIndexes">指定的列号（多列）</param>
        /// <param name="transposeOrNot">是否转置，默认为TRUE，即转置。</param>
        /// <returns>返回二维数组</returns>
        public static T[,] GetColumnsFrom2DArray<T>(T[,] Arr2D, int[] colIndexes, bool transposeOrNot = true)
        {
            T[,] resArr = new T[colIndexes.Length, Arr2D.GetLength(0)];
            for (int i = 0; i < colIndexes.Length; i++)
            {
                for (int j = 0; j < Arr2D.GetLength(0); j++)
                {
                    resArr[i, j] = Arr2D[j, i];
                }
            }

            if (transposeOrNot == false)
            {
                resArr = ArrayTranspose<T>(resArr);
            }
            return resArr;
        }

        /// <summary>
        /// 将数组转置，并返回一个新的二维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <returns>返回二维数组</returns>
        public static T[,] ArrayTranspose<T>(T[,] Arr2D)
        {
            T[,] resArr = new T[Arr2D.GetLength(1), Arr2D.GetLength(0)];
            for (int i = 0; i < resArr.GetLength(0); i++)
            {
                for (int j = 0; j < resArr.GetLength(1); j++)
                {
                    resArr[i, j] = Arr2D[j, i];
                }
            }
            return resArr;
        }

        [Obsolete("该方法已弃用，新方法为ArrayTranspose", false)]
        /// <summary>
        /// 将一维数组转置，并返回一个多行一列的二维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr1D">一维数组</param>
        /// <returns>返回二维数组</returns>
        public static T[,] ArrayTranspose_1Dto2D<T>(T[] Arr1D)
        {
            T[,] resArr = new T[Arr1D.Length, 1];
            for (int i = 0; i < Arr1D.Length; i++)
            {
                resArr[i, 0] = Arr1D[i];
            }
            return resArr;
        }

        /// <summary>
        /// 将数组转置，并返回一个二维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr1D">一维数组</param>
        /// <returns>返回二维数组</returns>
        public static T[,] ArrayTranspose<T>(T[] Arr1D)
        {
            T[,] resArr = new T[Arr1D.Length, 1];
            for (int i = 0; i < Arr1D.Length; i++)
            {
                resArr[i, 0] = Arr1D[i];
            }
            return resArr;
        }

        /// <summary>
        /// 将一个多行多列的二维数组转置，并返回一个一维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="Arr2D">二维数组</param>
        /// <returns>返回一个一维数组</returns>
        public static T[] ArrayTranspose_2Dto1D<T>(T[,] Arr2D)
        {
            T[] resArr = new T[Arr2D.GetLength(0) * Arr2D.GetLength(1)];
            for (int i = 0; i < Arr2D.GetLength(0); i++)
            {
                for (int j = 0; j < Arr2D.GetLength(1); j++)
                {
                    resArr[i] = Arr2D[i, j];
                }
            }
            return resArr;
        }

        /// <summary>
        /// 将IList转化为List。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ilist"></param>
        /// <returns></returns>
        public static List<T> IList2List<T>(IList<T> ilist)
        {
            if (ilist != null && ilist.Count > 0)
            {
                List<T> list = new List<T>();
                for (int i = 0; i < ilist.Count; i++)
                {
                    T temp = ilist[i];
                    if (temp != null)
                        list.Add(temp);
                }
                return list;
            }
            return null;
        }

        /// <summary>
        /// 生成一维整形数组
        /// </summary>
        /// <param name="start">起始值</param>
        /// <param name="step">步长</param>
        /// <param name="num">总个数</param>
        /// <returns>返回一维整形数组</returns>
        public static int[] IntArrayGenerator(int start, int step, int num)
        {
            int[] resArr = new int[num];
            for (int i = 0; i < num; i++)
            {
                resArr[i] = start + i * step;
            }
            return resArr;
        }

        /// <summary>
        /// 将单个元素拓展为固定长度的数组。
        /// </summary>
        /// <typeparam name="T">元素数据类型</typeparam>
        /// <param name="item">单个元素</param>
        /// <param name="num">数组长度</param>
        /// <returns>返回数组</returns>
        public static T[] ArrayInflator<T>(T item, int num)
        {
            T[] arr = new T[num];
            for (int i = 0; i < num; i++)
            {
                arr[i] = item;
            }
            return arr;
        }

        /// <summary>
        /// 将数字转换成固定长度的字符串输出
        /// </summary>
        /// <typeparam name="T">数字的数据类型</typeparam>
        /// <param name="num">数字</param>
        /// <param name="intLength">整数部分长度</param>
        /// <param name="decimalLength">小数部分长度</param>
        /// <returns>返回字符串</returns>
        public static string FixedLengthNumber<T>(T num, int intLength, int decimalLength = 0)
        {
            string resStr;
            string formatStr = "";
            for (int i = 0; i < intLength; i++)
            {
                formatStr += "0";
            }
            formatStr += ".";
            for (int i = 0; i < decimalLength; i++)
            {
                formatStr += "0";
            }
            resStr = string.Format("{0:" + formatStr + "}", num);
            return resStr;
        }

        /// <summary>
        /// 一维数组切片
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr">输入数组</param>
        /// <param name="indexArr">待切取的元素的index</param>
        /// <returns>返回数组</returns>
        public static T[] Array1DSlicing<T>(T[] inputArr, int[] indexArr)
        {
            T[] resArr = new T[indexArr.Length];
            for (int i = 0; i < indexArr.Length; i++)
            {
                //resArr[i] = inputArr.Skip<T>(indexArr[i]).Take<T>(1).ToArray()[0];
                resArr[i] = inputArr[indexArr[i]];
            }
            return resArr;
        }

        /// <summary>
        /// 一维数组去除指定元素。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr">输入数组</param>
        /// <param name="indexArr">待去除的元素的index</param>
        /// <returns>返回数组</returns>
        public static T[] Array1DDropElement<T>(T[] inputArr, int[] indexArr)
        {
            T[] resArr = new T[inputArr.Length - indexArr.Length];
            int j = 0;
            for (int i = 0; i < inputArr.Length; i++)
            {
                if (!indexArr.Contains<int>(i))
                {
                    resArr[j] = inputArr[i];
                    j++;
                }
            }
            return resArr;
        }

        /// <summary>
        /// 将二维数组按列切片，并返回二维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr2D">输入的二维数组</param>
        /// <param name="iColArr">待获取的列标</param>
        /// <returns>返回二维数组</returns>
        public static T[,] Array2DSlicing_ByCol<T>(T[,] inputArr2D, int[] iColArr)
        {
            T[,] resArr = new T[inputArr2D.GetLength(0), iColArr.Length];
            for (int i = 0; i < inputArr2D.GetLength(0); i++)
            {
                for (int j = 0; j < iColArr.Length; j++)
                {
                    resArr[i, j] = inputArr2D[i, iColArr[j]];
                }
            }
            return resArr;
        }

        /// <summary>
        /// 将二维数组按列切片，并返回一维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr2D">输入的二维数组</param>
        /// <param name="iCol">待获取的列标</param>
        /// <returns>返回一维数组</returns>
        public static T[] Array2DSlicing_ByCol<T>(T[,] inputArr2D, int iCol)
        {
            T[] resArr = new T[inputArr2D.GetLength(0)];
            for (int i = 0; i < inputArr2D.GetLength(0); i++)
            {
                resArr[i] = inputArr2D[i, iCol];
            }
            return resArr;
        }

        /// <summary>
        /// 将二维数组按行切片，并返回二维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr2D">输入的二维数组</param>
        /// <param name="iRowArr">待获取的行号</param>
        /// <returns>返回二维数组</returns>
        public static T[,] Array2DSlicing_ByRow<T>(T[,] inputArr2D, int[] iRowArr)
        {
            T[,] resArr = new T[iRowArr.Length, inputArr2D.GetLength(1)];
            for (int i = 0; i < iRowArr.Length; i++)
            {
                for (int j = 0; j < inputArr2D.GetLength(1); j++)
                {
                    resArr[i, j] = inputArr2D[iRowArr[i], j];
                }
            }
            return resArr;
        }

        /// <summary>
        /// 将二维数组按行切片，并返回一维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr2D">输入的二维数组</param>
        /// <param name="iRow">待获取的行号</param>
        /// <returns>返回一维数组</returns>
        public static T[] Array2DSlicing_ByRow<T>(T[,] inputArr2D, int iRow)
        {
            T[] resArr = new T[inputArr2D.GetLength(1)];
            for (int j = 0; j < inputArr2D.GetLength(1); j++)
            {
                resArr[j] = inputArr2D[iRow, j];
            }
            return resArr;
        }

        /// <summary>
        /// 将多个一维数组合并成新的一维数组。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="inputArr">输入的一维数组组成的数组</param>
        /// <returns>返回一维数组</returns>
        public static T[] ArraysUnion<T>(T[][] inputArr)
        {
            int length = 0;
            for (int i = 0; i < inputArr.Length; i++)
            {
                length += inputArr[i].Length;
            }
            T[] resArr = new T[length];
            int tempInt = 0;
            for (int i = 0; i < inputArr.Length; i++)
            {
                inputArr[i].CopyTo(resArr, tempInt);
                tempInt += inputArr[i].Length;
            }
            return resArr;
        }

        /// <summary>
        /// 计算数组指定区间目标元素的个数。
        /// </summary>
        /// <typeparam name="T">数组元素类型</typeparam>
        /// <param name="arr">目标数组</param>
        /// <param name="ele">目标元素</param>
        /// <param name="indexStart">起始序号（包含），默认为0。</param>
        /// <param name="len">指定区间长度，默认为0，即整个数组。</param>
        /// <returns></returns>
        public static int ArrayEleCount<T>(T[] arr, T ele, int indexStart = 0, int len = 0)
        {
            int c = 0;
            if (len == 0)
                len = arr.Length;
            for (int i = indexStart; i < len; i++)
            {
                if (arr[i].Equals(ele))
                    c++;
            }
            return c;
        }

        /// <summary>
        /// 计算数组指定区间满足指定条件的元素个数。
        /// </summary>
        /// <typeparam name="T">数组元素类型</typeparam>
        /// <param name="arr">目标数组</param>
        /// <param name="func">判断条件，第一个参数为arr[i]。</param>
        /// <param name="indexStart">起始序号（包含），默认为0。</param>
        /// <param name="len">指定区间长度，默认为0，即整个数组。</param>
        /// <returns></returns>
        public static int ArrayEleCount<T>(T[] arr, Func<T, bool> func, int indexStart = 0, int len = 0)
        {
            int c = 0;
            if (len == 0)
                len = arr.Length;
            for (int i = indexStart; i < len; i++)
            {
                if (func(arr[i]))
                    c++;
            }
            return c;
        }

        /// <summary>
        /// 将数组中个数大于1的元素及索引以字典的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的类型</typeparam>
        /// <param name="arr">数组</param>
        /// <param name="ignoreBlank">是否忽略空白元素，默认忽略</param>
        /// <returns>返回字典</returns>
        public static Dictionary<T, int[]> ArrayDuplicateValuesAndIndexes<T>(T[] arr, bool ignoreBlank = true)
        {
            Dictionary<T, int[]> resDict = new Dictionary<T, int[]>();
            if (ignoreBlank == true)
            {
                foreach (IGrouping<T, T> group in arr.GroupBy(x => x).Where(x => x.Count() > 1 && x.Key.ToString() != ""))
                {
                    int[] indexArr = new int[group.Count()];
                    indexArr = IndexesOf<T>(arr, group.Key);
                    resDict.Add(group.Key, indexArr);
                }
            }
            else
            {
                foreach (IGrouping<T, T> group in arr.GroupBy(x => x).Where(x => x.Count() > 1))
                {
                    int[] indexArr = new int[group.Count()];
                    indexArr = IndexesOf<T>(arr, group.Key);
                    resDict.Add(group.Key, indexArr);
                }
            }

            return resDict;
        }

        /// <summary>
        /// 判断数组是否包含重复元素。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static bool ArrayHasDuplicates<T>(T[] arr)
        {
            if (arr.Length != arr.Distinct().Count())
                return true;
            else
                return false;
        }

        /// <summary>
        /// 将数组中目标元素的全部索引以整形数组的形式返回。
        /// </summary>
        /// <typeparam name="T">数组元素的类型</typeparam>
        /// <param name="arr">数组</param>
        /// <param name="target">目标元素</param>
        /// <returns>返回整形数组</returns>
        public static int[] IndexesOf<T>(T[] arr, T target)
        {
            int[] res = new int[NumberOf<T>(arr, target)];
            int j = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] != null && target != null
                    && arr[i].ToString() == target.ToString())
                {
                    res[j] = i;
                    j++;
                }
            }
            return res;
        }

        /// <summary>
        /// 在数组中查询第一个与目标值相匹配的元素的序号。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="arr">数组</param>
        /// <param name="target">目标值</param>
        /// <returns>返回匹配元素的序号，如果无匹配项，则返回-1</returns>
        public static int FirstIndexOf<T>(T[] arr, T target)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i].ToString() == target.ToString())
                    return i;
            }
            return -1;//如果无匹配项，则返回-1。
        }

        /// <summary>
        /// 在数组中查询最后一个与目标值相匹配的元素的序号。
        /// </summary>
        /// <typeparam name="T">数组元素的数据类型</typeparam>
        /// <param name="arr">数组</param>
        /// <param name="target">目标值</param>
        /// <returns>返回匹配元素的序号，如果无匹配项，则返回-1</returns>
        public static int LastIndexOf<T>(T[] arr, T target)
        {
            int[] res = IndexesOf<T>(arr, target);
            if (res.Length != 0)
                return res[res.Length - 1];
            else
                return -1;
        }

        /// <summary>
        /// 返回数组中目标元素的个数。
        /// </summary>
        /// <typeparam name="T">数组元素的类型</typeparam>
        /// <param name="arr">数组</param>
        /// <param name="target">目标元素</param>
        /// <returns>返回数组中目标元素的个数</returns>
        public static int NumberOf<T>(T[] arr, T target)
        {
            int res = 0;
            foreach (T item in arr)
            {
                if (item != null && target != null && item.ToString() == target.ToString())
                    res++;
            }
            return res;
        }
    }

    /// <summary>
    /// 字符串处理工具
    /// </summary>
    public class StringUtility
    {
        /// <summary>
        /// 获取文件名（含后缀）或文件夹名称
        /// </summary>
        /// <param name="path">完整路径</param>
        /// <returns></returns>
        public static string GetFileFolderName(string path)
        {
            if (string.IsNullOrEmpty(path))
                return string.Empty;

            string normalizedPath = path.Replace('/', '\\');

            int i_last = normalizedPath.LastIndexOf('\\');
            if (i_last <= 0)
                return normalizedPath;
            return normalizedPath.Substring(i_last + 1);
        }

        /// <summary>
        /// 修改文件名后缀，并返回新的文件名。
        /// </summary>
        /// <param name="fileName">原文件名</param>
        /// <param name="newSuffix">新的后缀，注意不带“.”</param>
        /// <returns>返回新文件名</returns>
        public static string ModifyFileSuffix(string fileName, string newSuffix)
        {
            string resStr = fileName.Substring(0, fileName.LastIndexOf('.') + 1) + newSuffix;
            return resStr;
        }

        /// <summary>
        /// 获取完整文件名，不包括后缀和“."。
        /// </summary>
        /// <param name="fileName">原文件名</param>
        /// <returns>返回完整文件名，不包括后缀和“."。</returns>
        public static string GetFullFileName_ExcludingSuffix(string fileName)
        {
            string resStr = fileName.Substring(0, fileName.LastIndexOf('.'));
            return resStr;
        }

        /// <summary>
        /// 获取文件类型（不用FileInfo）。
        /// </summary>
        /// <param name="fileName">完整文件名</param>
        /// <returns>返回文件类型</returns>
        public static string GetFileType(string fileName)
        {
            return fileName.Substring(fileName.LastIndexOf('.') + 1, fileName.Length - fileName.LastIndexOf('.') - 1);
        }

        /// <summary>
        /// 判断文件类型是否为目标格式。如果文件类型等于目标文件类型，或目标文件类型为空，则返回true，否则返回false。
        /// </summary>
        /// <param name="fileName">完整文件名</param>
        /// <param name="fileType_Target">目标文件类型</param>
        /// <returns>返回bool值</returns>
        public static bool IsTargetFileFormat(string fileName, string fileType_Target)
        {
            bool retVal = true;
            string fileType = GetFileType(fileName);
            if (!string.IsNullOrEmpty(fileType_Target) && fileType.ToUpper() != fileType_Target.ToUpper())
            {
                retVal = false;
            }
            return retVal;
        }

        /// <summary>
        /// 判断文件类型是否为目标格式（多个格式）。
        /// </summary>
        /// <param name="fileName">完整文件名</param>
        /// <param name="fileTypeArr_Target">目标文件类型数组</param>
        /// <returns>返回bool值</returns>
        public static bool IsTargetFileFormats(string fileName, string[] fileTypeArr_Target)
        {
            for (int i = 0; i < fileTypeArr_Target.Length; i++)
            {
                if (IsTargetFileFormat(fileName, fileTypeArr_Target[i]))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获取文件信息。
        /// </summary>
        /// <param name="filePath">文件完整路径</param>
        /// <returns>输出一个5个元素的字符串数组，分别是：文件名（0）、修改时间（1）、大小（2）、文件类型（3）、路径（4）。</returns>
        public static string[] GetFileInfo(string filePath)
        {
            string[] strArr = new string[5];
            /*  ================
             *  Index   内容
             *  ----------------
             *  0       文件名
             *  1       修改时间
             *  2       大小
             *  3       文件类型
             *  4       路径
             *  ================
             */

            //获取文件名
            FileInfo fileInfo = new FileInfo(filePath);
            strArr[0] = fileInfo.Name.ToString();
            strArr[1] = fileInfo.LastWriteTime.ToString();
            strArr[2] = Math.Ceiling(fileInfo.Length / 1024.0) + " KB";
            strArr[3] = fileInfo.Extension.ToString().Replace(".", string.Empty);
            strArr[4] = filePath;

            return strArr;
        }

        /// <summary>
        /// 获取一个文件夹下所有文件的文件名，并以字符串数组的形式返回。
        /// </summary>
        /// <param name="folderPath">母文件夹路径</param>
        /// <returns>返回字符串数组</returns>
        public static string[] GetFileNamesInOneFolder(string folderPath)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
            FileInfo[] fileInfo = directoryInfo.GetFiles();
            string[] resArr = new string[fileInfo.Length];
            for (int i = 0; i < fileInfo.Length; i++)
            {
                resArr[i] = fileInfo[i].Name.ToString();
            }
            return resArr;
        }

        /// <summary>
        /// 获取一个文件夹下所有文件夹的名称，并以字符串数组的形式返回。
        /// </summary>
        /// <param name="folderPath">母文件夹路径</param>
        /// <returns>返回字符串数组</returns>
        public static string[] GetFolderNamesInOneFolder(string folderPath)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
            DirectoryInfo[] folderInfo = directoryInfo.GetDirectories();
            string[] resArr = new string[folderInfo.Length];
            for (int i = 0; i < folderInfo.Length; i++)
            {
                resArr[i] = folderInfo[i].Name.ToString();
            }
            return resArr;
        }

        /// <summary>
        /// 返回文件路径（不包括文件名，末尾没有“\”）
        /// </summary>
        /// <param name="filePath">完整的文件名</param>
        /// <returns>返回文件路径（不包括文件名）</returns>
        public static string GetFilePath_ExcludingFileName(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return filePath.Replace("\\" + fileInfo.Name, "");
        }

        /// <summary>
        /// 返回文件名（不包括文件路径，包括后缀）。
        /// </summary>
        /// <param name="filePath">完整的文件名</param>
        /// <returns>返回文件名</returns>
        public static string GetFileName(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return fileInfo.Name;
        }

        /// <summary>
        /// 获取文件的短名称。
        /// 详见：https://stackoverflow.com/questions/2585171/getshortpathnamea-not-working-in-c-sharp
        /// </summary>
        /// <param name="sLongFileName">文件的长名称</param>
        /// <param name="cchBuffer">返回的短名称bit长度，默认为255 bit</param>
        /// <returns>返回文件的短名称</returns>
        public static string GetShortName(string sLongFileName, int cchBuffer = 255)
        {
            StringBuilder buffer = new StringBuilder(cchBuffer);
            int len = GetShortPathName(sLongFileName, buffer, buffer.Capacity);
            if (len == 0) throw new System.ComponentModel.Win32Exception();
            return buffer.ToString();
        }

        [DllImport("kernel32", EntryPoint = "GetShortPathName", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetShortPathName(string longPath, StringBuilder shortPath, int bufSize);
        /// <summary>
        /// 返回文件名（不包括文件路径和后缀）
        /// </summary>
        /// <param name="filePath">完整的文件名</param>
        /// <returns>返回文件名</returns>
        public static string GetFileName_ExcludingSuffix(string filePath)
        {
            if (!System.IO.File.Exists(filePath))
                return filePath;
            string res = GetFileName(filePath);
            return res.Substring(0, res.LastIndexOf('.'));
        }

        /// <summary>
        /// 计算两个字符串之间的Levenshtein Distance
        /// </summary>
        /// <param name="s">字符串1</param>
        /// <param name="t">字符串2</param>
        /// <returns>返回整形</returns>
        public static int LevenshteinDistance(string s, string t)
        {
            if (string.IsNullOrEmpty(s))
            {
                if (string.IsNullOrEmpty(t))
                    return 0;
                return t.Length;
            }

            if (string.IsNullOrEmpty(t))
            {
                return s.Length;
            }

            int n = s.Length;
            int m = t.Length;
            int[,] d = new int[n + 1, m + 1];

            // initialize the top and right of the table to 0, 1, 2, ...
            for (int i = 0; i <= n; d[i, 0] = i++) ;
            for (int j = 1; j <= m; d[0, j] = j++) ;

            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
                    int min1 = d[i - 1, j] + 1;
                    int min2 = d[i, j - 1] + 1;
                    int min3 = d[i - 1, j - 1] + cost;
                    d[i, j] = Math.Min(Math.Min(min1, min2), min3);
                }
            }
            return d[n, m];
        }

        /// <summary>
        /// 返回字符串相似度（Levenshtein Distance，取值范围为0~1）。
        /// </summary>
        /// <param name="source">字符串1</param>
        /// <param name="target">字符串2</param>
        /// <returns>返回百分比</returns>
        public static double LevenshteinDistance_0_1(string source, string target)
        {
            if ((source == null) || (target == null)) return 0.0;
            if (source == target) return 1.0;
            if ((source.Length == 0) || (target.Length == 0)) return 0.0;

            int stepsToSame = LevenshteinDistance(source, target);
            return (1.0 - ((double)stepsToSame / (double)Math.Max(source.Length, target.Length)));
        }

        /// <summary>
        /// 比较两个字符串中相同的字符个数。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static int SimilarCharacterCount(string str0, string str1)
        {
            int res = 0;

            if (string.IsNullOrEmpty(str0) || string.IsNullOrEmpty(str1))
                return res;

            List<char> cs0 = str0.ToList();
            List<char> cs1 = str1.ToList();
            for (int i = 0; i < cs1.Count; i++)
            {
                if (cs0.Count <= 0)
                    break;

                if (cs0.Contains(cs1[i]))
                {
                    cs0.Remove(cs1[i]);
                    res++;
                }
            }
            return res;
        }

        /// <summary>
        /// 比较两个字符串中相同的字符个数，考虑字符顺序。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static int SimilarCharacterCount_ConsiderSequence(string str0, string str1)
        {
            int res = 0;

            if (string.IsNullOrEmpty(str0) || string.IsNullOrEmpty(str1))
                return res;

            List<char> cs0 = str0.ToList();
            List<char> cs1 = str1.ToList();
            for (int i = 0; i < cs1.Count; i++)
            {
                if (cs0.Count <= 0)
                    break;

                if (cs0.Contains(cs1[i]))
                {
                    cs0.RemoveRange(0, cs0.IndexOf(cs1[i]) + 1);
                    res++;
                }
            }
            return res;
        }

        /// <summary>
        /// 返回字符串相似度（不考虑字符的排列顺序，取值范围为0~1）。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static double Similarity_IgnoreSequence(string str0, string str1)
        {
            if (string.IsNullOrEmpty(str0) || string.IsNullOrEmpty(str1))
                return 0.0;

            int sc = SimilarCharacterCount(str0, str1);
            return ((double)sc / (double)Math.Max(str0.Length, str1.Length));
        }

        /// <summary>
        /// 返回字符串相似度（考虑字符的排列顺序，取值范围为0~1）。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static double Similarity_ConsiderSequence(string str0, string str1)
        {
            if (string.IsNullOrEmpty(str0) || string.IsNullOrEmpty(str1))
                return 0.0;
            int sc = SimilarCharacterCount_ConsiderSequence(str0, str1);
            return ((double)sc / (double)Math.Max(str0.Length, str1.Length));
        }

        /// <summary>
        /// 返回字符串相似度（考虑字符的排列顺序，全包含，取值范围为0~2，大于1时，为全包含）。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static double Similarity_ConsiderSequence_FullContain(string str0, string str1)
        {
            double res = Similarity_ConsiderSequence(str0, str1);
            if (IsAllLettersContained_IncludingDuplicates(str0, str1))
            {
                res += 1;
            }
            return res;
        }

        /// <summary>
        /// 判断是否str0包含str1中的所有字符，不去重。
        /// </summary>
        /// <param name="str0">被比较字符串</param>
        /// <param name="str1">比较字符串</param>
        /// <returns></returns>
        public static bool IsAllLettersContained_IncludingDuplicates(string str0, string str1)
        {
            for (int i = 0; i < str1.Length; i++)
            {
                if (!str0.Contains(str1[i]))
                {
                    return false;
                }
                else
                {
                    str0 = str0.Remove(str0.IndexOf(str1[i]), 1);
                }
            }
            return true;
        }

        /// <summary>
        /// 将两个字符串数组进行相似度匹配，并返回字符串数组。
        /// </summary>
        /// <param name="strArr0">标杆字符串数组</param>
        /// <param name="strArr1">待匹配的字符串数组，其长度需要不小于标杆字符串数组。</param>
        /// <param name="simFunc">相似度函数，默认是LevenshteinDistance_0_1</param>
        /// <returns>返回字符串数组</returns>
        public static string[] SimMapping_StrArr_To_StrArr(
            string[] strArr0,
            string[] strArr1,
            Func<string, string, double> simFunc = null
            )
        {
            if (simFunc == null)
                simFunc = LevenshteinDistance_0_1;
            string[] resArr = new string[strArr0.Length];
            string[] strArr1_New = strArr1;
            for (int i = 0; i < strArr0.Length; i++)
            {
                resArr[i] = SimMostString(strArr0[i], strArr1_New, simFunc);
                strArr1_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1_New, resArr[i]) }
                    );
            }
            return resArr;
        }

        /// <summary>
        /// 将两个字符串数组进行正则匹配，并返回字符串数组。
        /// </summary>
        /// <param name="strArr0">标杆字符串数组</param>
        /// <param name="strArr1">待匹配的字符串数组，其长度需要不小于标杆字符串数组。</param>
        /// <returns>返回字符串数组</returns>
        public static string[] RegexMapping_StrArr_To_StrArr(string[] strArr0, string[] strArr1)
        {
            string[] resArr = new string[strArr0.Length];
            string[] strArr1_New = strArr1;
            for (int i = 0; i < strArr0.Length; i++)
            {
                resArr[i] = MyVlookUp(strArr0[i], strArr1_New, 1);
                strArr1_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1_New, resArr[i]) }
                    );
            }
            return resArr;
        }

        /// <summary>
        /// 仿照Excel中的Match函数构建。
        /// </summary>
        /// <param name="strMatch">匹配字符串，适用正则表达式。</param>
        /// <param name="strArr">待匹配的字符串数组。</param>
        /// <param name="index">第几个满足匹配条件的元素，默认为第一个。如果想获取最后一个，填“-1”即可。</param>
        /// <returns>返回目标元素的序号，如果返回结果为-1，则表示未匹配到结果。</returns>
        public static int MyMatch(string strMatch, string[] strArr, int index = 1)
        {
            int i_res = 0;
            int res = -1;
            for (int i = 0; i < strArr.Length; i++)
            {
                if (Regex_Common.isMatch(strArr[i], strMatch))   //如果匹配到结果
                {
                    i_res++;
                    res = i;
                    if (i_res == index)
                        return res;
                }
            }

            return res;
        }

        /// <summary>
        /// 仿照Excel中的VlookUp函数构建。
        /// </summary>
        /// <param name="strMatch">匹配字符串，适用正则表达式。</param>
        /// <param name="strArr">待匹配的字符串数组。</param>
        /// <param name="index">第几个满足匹配条件的元素，默认为第一个。如果想获取最后一个，填“-1”即可。</param>
        /// <param name="strHolder">未匹配到结果时返回的字符串，默认为"【未匹配到结果】"。</param>
        /// <returns>返回目标元素。</returns>
        public static string MyVlookUp(string strMatch, string[] strArr, int index = 1, string strHolder = "【未匹配到结果】")
        {
            int iRes = StringUtility.MyMatch(strMatch, strArr, index);
            if (iRes != -1)
                return strArr[iRes];
            else
                return strHolder;
        }

        /// <summary>
        /// 将字符串数组与一个字符串数组的影子数组进行相似度匹配，并返回字符串数组。
        /// </summary>
        /// <param name="strArr0">标杆字符串数组</param>
        /// <param name="strArr1">待匹配的字符串数组，其长度需要不小于标杆字符串数组。</param>
        /// <param name="strArr1Shadow">待匹配字符串数组的影子数组</param>
        /// <param name="simFunc">相似度函数，默认是LevenshteinDistance_0_1</param>
        /// <returns>返回字符串数组</returns>
        public static string[] SimMapping_StrArr_To_StrArrShadow(
            string[] strArr0,
            string[] strArr1,
            string[] strArr1Shadow,
            Func<string, string, double> simFunc = null
            )
        {
            if (simFunc == null)
                simFunc = LevenshteinDistance_0_1;
            string[] resArr1 = new string[strArr0.Length];
            string[] resArr1Shadow = new string[strArr0.Length];
            string[] strArr1_New = strArr1;
            string[] strArr1Shadow_New = strArr1Shadow;
            for (int i = 0; i < strArr0.Length; i++)
            {
                resArr1[i] = strArr1_New[SimMostString_RtnIndex(strArr0[i], strArr1Shadow_New, simFunc)];
                resArr1Shadow[i] = SimMostString(strArr0[i], strArr1Shadow_New, simFunc);
                strArr1Shadow_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1Shadow_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1Shadow_New, resArr1Shadow[i]) }
                    );
                strArr1_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1_New, resArr1[i]) }
                    );
            }
            return resArr1;
        }

        /// <summary>
        /// 将字符串数组与一个字符串数组的影子数组进行正则匹配，并返回字符串数组。
        /// </summary>
        /// <param name="strArr0">标杆字符串数组</param>
        /// <param name="strArr1">待匹配的字符串数组，其长度需要不小于标杆字符串数组。</param>
        /// <param name="strArr1Shadow">待匹配字符串数组的影子数组</param>
        /// <param name="strHolder">未匹配到结果时返回的字符串，默认为"【未匹配到结果】"。</param>
        /// <returns>返回字符串数组</returns>
        public static string[] RegexMapping_StrArr_To_StrArrShadow(string[] strArr0, string[] strArr1, string[] strArr1Shadow, string strHolder = "【未匹配到结果】")
        {
            string[] resArr1 = new string[strArr0.Length];
            string[] resArr1Shadow = new string[strArr0.Length];
            string[] strArr1_New = strArr1;
            string[] strArr1Shadow_New = strArr1Shadow;
            for (int i = 0; i < strArr0.Length; i++)
            {
                int iTemp = MyMatch(strArr0[i], strArr1Shadow_New, 1);
                if (iTemp != -1)
                    resArr1[i] = strArr1_New[iTemp];
                else
                    resArr1[i] = strHolder;
                resArr1Shadow[i] = MyVlookUp(strArr0[i], strArr1Shadow_New, 1, strHolder);
                strArr1Shadow_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1Shadow_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1Shadow_New, resArr1Shadow[i]) }
                    );
                strArr1_New = BasicDataProcess_Common.Array1DDropElement<string>(
                    strArr1_New,
                    new int[] { BasicDataProcess_Common.FirstIndexOf<string>(strArr1_New, resArr1[i]) }
                    );
            }
            return resArr1;
        }

        /// <summary>
        /// 从一个字符串数组中找出与目标字符串最相似的字符串，并返回。
        /// </summary>
        /// <param name="str0">目标字符串</param>
        /// <param name="strArr">待匹配的字符串数组</param>
        /// <param name="simFunc">相似度函数，默认是LevenshteinDistance_0_1</param>
        /// <returns>返回字符串数组</returns>
        public static string SimMostString(
            string str0,
            string[] strArr,
            Func<string, string, double> simFunc = null
            )
        {
            if (simFunc == null)
                simFunc = LevenshteinDistance_0_1;
            double[] simArr = new double[strArr.Length];
            for (int i = 0; i < simArr.Length; i++)
            {
                simArr[i] = simFunc(str0, strArr[i]);
            }
            return strArr[BasicDataProcess_Common.FirstIndexOf<double>(simArr, simArr.Max())];
        }

        /// <summary>
        /// 从一个字符串数组中找出与目标字符串最相似的字符串，并返回该元素的序号。
        /// </summary>
        /// <param name="str0">目标字符串</param>
        /// <param name="strArr">待匹配的字符串数组</param>
        /// <param name="simFunc">相似度函数，默认是LevenshteinDistance_0_1</param>
        /// <returns>返回目标元素的序号</returns>
        public static int SimMostString_RtnIndex(
            string str0,
            string[] strArr,
            Func<string, string, double> simFunc = null
            )
        {
            if (simFunc == null)
                simFunc = LevenshteinDistance_0_1;
            double[] simArr = new double[strArr.Length];
            for (int i = 0; i < simArr.Length; i++)
            {
                simArr[i] = simFunc(str0, strArr[i]);
            }
            return BasicDataProcess_Common.FirstIndexOf<double>(simArr, simArr.Max());
        }

        /// <summary>
        /// 将英文词组各单词首字母转换成大写。
        /// </summary>
        /// <param name="str0">原字符串</param>
        /// <returns>返回字符串</returns>
        public static string InitialsToUpper(string str0)
        {
            string[] tempArr = str0.Split(' ');
            string temp = "";
            for (int i = 0; i < tempArr.Length; i++)
            {
                temp += InitialToUpper(tempArr[i]);
            }
            return temp;
        }

        /// <summary>
        /// 将英文词组各单词首字母转换成大写（驼峰命名法）。
        /// </summary>
        /// <param name="str0">原字符串</param>
        /// <returns>返回字符串</returns>
        public static string InitialsToUpperHump(string str0)
        {
            string[] tempArr = str0.Split(' ');
            string temp = tempArr[0];
            temp = temp[0].ToString().ToLower() + temp.Substring(1, temp.Length - 1);
            for (int i = 1; i < tempArr.Length; i++)
            {
                temp += InitialToUpper(tempArr[i]);
            }
            return temp;
        }

        /// <summary>
        /// 将单个英文单词首字母转换成大写。
        /// </summary>
        /// <param name="word">原单词</param>
        /// <returns>返回新单词</returns>
        private static string InitialToUpper(string word)
        {
            return word[0].ToString().ToUpper() + word.Substring(1, word.Length - 1);
        }
    }
}
